home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / filesys.asm < prev    next >
Assembly Source File  |  1998-01-20  |  8KB  |  370 lines

  1.     SECTION code
  2. ; This file can be translated with A68k or PhxAss and then linked with BLink
  3. ; to produce an Amiga executable. Make sure it does not contain any
  4. ; relocations, then run it through the filesys.sh script
  5.  
  6.     dc.l 16
  7. our_seglist:
  8.     dc.l 0 ;/* NextSeg */
  9. start:
  10.     bra filesys_mainloop
  11.     dc.l make_dev-start
  12.     dc.l filesys_init-start
  13.     dc.l exter_server-start
  14.     dc.l bootcode-start
  15.  
  16. bootcode:
  17.     lea.l doslibname(pc),a1
  18.     jsr.l -96(a6) ; FindResident
  19.     move.l d0,a0
  20.     move.l 22(a0),d0
  21.     move.l d0,a0
  22.     jsr (a0)
  23.     rts
  24.  
  25. exter_data:
  26. exter_server:
  27.     movem.l a2,-(sp)
  28.     moveq.l #0,d0
  29.     jsr.l $F0FF50
  30.     tst.l d0
  31.     beq.b exter_server_exit
  32.     ; This is the hard part - we have to send some messages.
  33.     move.l 4.w,a6
  34. EXTS_loop:
  35.     moveq.l #2,d0
  36.     jsr.l $F0FF50
  37.     tst.l d0
  38.     beq.b EXTS_done
  39.     move.l d0,a2
  40.     moveq.l #3,d0
  41.     jsr.l $F0FF50
  42.     move.l a2,a0
  43.     move.l d0,a1
  44.     jsr -366(a6) ; PutMsg
  45.     bra.b EXTS_loop
  46.  
  47. EXTS_done:
  48.     moveq.l #4,d0
  49.     jsr.l $F0FF50
  50.     moveq.l #1,d0 ; clear Z - it was for us.
  51. exter_server_exit:
  52.     movem.l (sp)+,a2
  53.     rts
  54.  
  55. filesys_init:
  56.     movem.l d0-d7/a0-a6,-(sp)
  57.     move.l 4.w,a6
  58.     move.l $F0FFFC,a5 ; filesys base
  59.     lea.l explibname(pc),a1 ; expansion lib name
  60.     moveq.l #36,d0
  61.     moveq.l #0,d5
  62.     jsr.l  -552(a6) ; OpenLibrary
  63.     tst.l d0
  64.     bne.b FSIN_explibok
  65.     lea.l explibname(pc),a1 ; expansion lib name
  66.     moveq.l #0,d0
  67.     moveq.l #1,d5
  68.     jsr.l  -552(a6) ; OpenLibrary
  69. FSIN_explibok:
  70.     move.l d0,a4
  71.     moveq.l #88,d0
  72.     moveq.l #1,d1 ; MEMF_PUBLIC
  73.     jsr.l -198(a6) ; AllocMem
  74.     move.l d0,a3  ; param packet
  75.  
  76.     moveq.l #84,d7 ; initialize it
  77. FSIN_loop:
  78.     move.l 0(a5,d7.l),0(a3,d7.l)
  79.     subq.l #4,d7
  80.     bcc.b FSIN_loop
  81.  
  82.     moveq.l #0,d6
  83. FSIN_init_units:
  84.     cmp.l  $10c(a5),d6
  85.     bcc.b FSIN_units_ok
  86.     move.l a3,a0
  87.     movem.l d6/a3,-(sp)
  88.     move.l  #1,d7
  89.     bsr.b   make_dev
  90.     movem.l (sp)+,d6/a3
  91.     addq.l #$1,d6
  92.     bra.b  FSIN_init_units
  93.  
  94. FSIN_units_ok:
  95.     move.l 4.w,a6
  96.     move.l a4,a1
  97.     jsr.l -414(a6) ; CloseLibrary
  98.     bsr.b setup_exter
  99.     move.l 4.w,a6
  100.     jsr.l $F0FF80
  101.     moveq.l #3,d1
  102.     moveq.l #-10,d2
  103.     move.l #$200000,a0
  104.     sub.l a0,d0
  105.     bcs.b FSIN_chip_done
  106.     beq.b FSIN_chip_done
  107.     moveq.l #0,d4
  108.     move.l d4,a1
  109.     jsr -618(a6)
  110. FSIN_chip_done
  111.     movem.l (sp)+,d0-d7/a0-a6
  112. general_ret:
  113.     rts
  114.  
  115. setup_exter:
  116.     move.l 4.w,a6
  117.     moveq.l #26,d0
  118.     move.l #$10001,d1
  119.     jsr -198(a6) ; AllocMem
  120.     move.l d0,a1
  121.     lea.l exter_name(pc),a0
  122.     move.l a0,10(a1)
  123.     lea.l exter_data(pc),a0
  124.     move.l a0,14(a1)
  125.     lea.l exter_server(pc),a0
  126.     move.l a0,18(a1)
  127.     moveq.l #13,d0
  128.     jmp.l -168(a6) ; AddIntServer
  129.  
  130. make_dev: ; IN: A0 param_packet, D6: unit_no, D7: boot, A4: expansionbase
  131.     move.l $F0FFFC,a5 ; filesys base
  132.  
  133.     jsr $F0FF28 ; fill in unit-dependent info, return 1 if hardfile.
  134.     move.l d0,d3
  135.  
  136.     ; Don't init hardfiles if < V36
  137.     and.l d5,d0
  138.     bne.b general_ret
  139.  
  140.     move.l a4,a6
  141.     jsr.l -144(a6) ; MakeDosNode()
  142.     move.l d0,a3 ; devicenode
  143.     jsr.l $F0FF20 ; record in ui.startup
  144.     moveq.l #0,d0
  145.     move.l d0,8(a3)          ; dn_Task
  146.     move.l d0,16(a3)         ; dn_Handler
  147.     move.l d0,32(a3)         ; dn_SegList
  148.  
  149.     tst.l d3
  150.     bne.b MKDV_doboot
  151.  
  152. MKDV_is_filesys:
  153.     move.l #4000,20(a3)     ; dn_StackSize
  154.     lea.l our_seglist(pc),a1
  155.     move.l a1,d0
  156.     lsr.l  #2,d0
  157.     move.l d0,32(a3)        ; dn_SegList
  158.     move.l #-1,36(a3)       ; dn_GlobalVec
  159.  
  160. MKDV_doboot:
  161.     tst.l d7
  162.     beq.b MKDV_noboot
  163.  
  164.     move.l 4.w,a6
  165.     moveq.l #20,d0
  166.     moveq.l #0,d1
  167.     jsr.l  -198(a6) ; AllocMem
  168.     move.l d0,a1 ; bootnode
  169.     moveq.l #0,d0
  170.     move.l d0,(a1)
  171.     move.l d0,4(a1)
  172.     move.w d0,14(a1)
  173.     move.w #$10FF,d0
  174.     sub.b  d6,d0
  175.     move.w d0,8(a1)
  176.     move.l $104(a5),10(a1) ; filesys_configdev
  177.     move.l a3,16(a1)        ; devicenode
  178.     lea.l  74(a4),a0 ; MountList
  179.     jmp.l  -270(a6) ; Enqueue()
  180.  
  181. MKDV_noboot:
  182.     move.l a3,a0
  183.     moveq.l #0,d1
  184.     move.l d1,a1
  185.     moveq.l #-1,d0
  186.     move.l a4,a6 ; expansion base
  187.     jmp.l  -150(a6) ; AddDosNode
  188.  
  189. filesys_mainloop:
  190.     move.l 4.w,a6
  191.     moveq.l #0,d0
  192.     move.l d0,a1
  193.     jsr -294(a6) ; FindTask
  194.     move.l d0,a0
  195.     lea.l $5c(a0),a5 ; pr_MsgPort
  196.  
  197.     ; Open DOS library
  198.     lea.l doslibname(pc),a1
  199.     moveq.l #0,d0
  200.     jsr -552(a6) ; OpenLibrary
  201.     move.l d0,a2
  202.  
  203.     ; Allocate some memory. Usage:
  204.     ; 0: lock chain
  205.     ; 4: command chain
  206.     ; 8: second thread's lock chain
  207.     ; 12: dummy message
  208.     ; 32: the volume (80+44+1 bytes)
  209.     move.l #80+44+1+20+12,d0
  210.     move.l #$10001,d1 ; MEMF_PUBLIC | MEMF_CLEAR
  211.     jsr.l -198(a6) ; AllocMem
  212.     move.l d0,a3
  213.     moveq.l #0,d6
  214.     move.l d6,(a3)
  215.     move.l d6,4(a3)
  216.     move.l d6,8(a3)
  217.  
  218.     moveq.l #0,d5 ; No commands queued.
  219.  
  220.     ; Fetch our startup packet
  221.     move.l a5,a0
  222.     jsr -384(a6) ; WaitPort
  223.     move.l a5,a0
  224.     jsr -372(a6) ; GetMsg
  225.     move.l d0,a4
  226.     move.l 10(a4),d3 ; ln_Name
  227.     moveq.l #0,d0
  228.     jsr.l $F0FF40
  229.     bra.b FSML_Reply
  230.  
  231.     ; We abuse some of the fields of the message we get. Offset 0 is
  232.     ; used for chaining unprocessed commands, and offset 1 is used for
  233.     ; indicating the status of a command. 0 means the command was handed
  234.     ; off to some UAE thread and did not complete yet, 1 means we didn't
  235.     ; even hand it over yet because we were afraid that might blow some
  236.     ; pipe limit, and -1 means the command was handed over and has completed
  237.     ; processing by now, so it's safe to reply to it.
  238.  
  239. FSML_loop:
  240.     move.l a5,a0
  241.     jsr -384(a6) ; WaitPort
  242.     move.l a5,a0
  243.     jsr -372(a6) ; GetMsg
  244.     move.l d0,a4
  245.     move.l 10(a4),d3 ; ln_Name
  246.     bne.b FSML_FromDOS
  247.  
  248.     ; It's a dummy packet indicating that some queued command finished.
  249.     moveq.l #1,d0
  250.     jsr.l $F0FF50
  251.     ; Go through the queue and reply all those that finished.
  252.     lea.l 4(a3),a2
  253.     move.l (a2),a0
  254. FSML_check_old:
  255.     move.l a0,d0
  256.     beq.b FSML_loop
  257.     move.l (a0),a1
  258.     move.l d0,a0
  259.     ; This field may be accessed concurrently by several UAE threads.
  260.     ; This _should_ be harmless on all reasonable machines.
  261.     move.l 4(a0),d0
  262.     bpl.b FSML_check_next
  263.     movem.l a0/a1,-(a7)
  264.     move.l 10(a0),a4
  265.     bsr.b ReplyOne
  266.     subq.l #1,d5  ; One command less in the queue
  267.     movem.l (a7)+,a0/a1
  268.     move.l a1,(a2)
  269.     move.l a1,a0
  270.     bra.b FSML_check_old
  271. FSML_check_next:
  272.     move.l a0,a2
  273.     move.l a1,a0
  274.     bra.b FSML_check_old
  275.  
  276. FSML_FromDOS:
  277.     ; Limit the number of outstanding started commands. We can handle an
  278.     ; unlimited number of unstarted commands.
  279.     cmp.l #20,d5
  280.     bcs  FSML_DoCommand
  281.     ; Too many commands queued.
  282.     moveq.l #1,d0
  283.     move.l d0,4(a4)
  284.     bra.b FSML_Enqueue
  285.  
  286. FSML_DoCommand:
  287.     bsr.b LockCheck  ; Make sure there are enough locks for the C code to grab.
  288.     jsr.l $F0FF30
  289.     tst.l d0
  290.     beq.b FSML_Reply
  291.     ; The command did not complete yet. Enqueue it and increase number of
  292.     ; queued commands
  293.     ; The C code already set 4(a4) to 0
  294.     addq.l #1,d5
  295. FSML_Enqueue:
  296.     move.l 4(a3),(a4)
  297.     move.l a4,4(a3)
  298.     bra.b FSML_loop
  299.  
  300. FSML_Reply:
  301.     move.l d3,a4
  302.     bsr.b ReplyOne
  303.     bra.b FSML_loop
  304.  
  305. ReplyOne:
  306.     move.l (a4),a1  ; dp_Link
  307.     move.l 4(a4),a0 ; dp_Port
  308.     move.l a5,4(a4)
  309.     jmp -366(a6) ; PutMsg
  310.  
  311. ; ugly code to avoid calling AllocMem / FreeMem from native C code.
  312. ; We keep a linked list of 3 locks. In theory, only one should ever
  313. ; be used. Before handling every packet, we check that the list has the
  314. ; right length.
  315.  
  316. LockCheck:
  317.     move.l d5,-(a7)
  318.     moveq.l #-4,d5  ; Keep three locks
  319.     move.l (a3),a2
  320.     move.l a2,d7
  321. LKCK_Loop:
  322.     move.l a2,d1
  323.     beq LKCK_ListEnd
  324.     addq.l #1,d5
  325.     beq.b LKCK_TooMany
  326.     move.l a2,a1
  327.     move.l (a2),a2
  328.     bra.b LKCK_Loop
  329. LKCK_ListEnd:
  330.     addq.l #1,d5
  331.     beq.b LKCK_ret
  332.     move.l d7,a2
  333.     moveq.l #24,d0 ; sizeof Lock is 20, 4 for chain
  334.     moveq.l #1,d1 ; MEMF_PUBLIC
  335.     jsr.l -198(a6) ; AllocMem
  336.     addq.w #1,d6
  337.     move.l d0,a2
  338.     move.l d7,(a2)
  339.     move.l a2,d7
  340.     bra.b LKCK_ListEnd
  341. LKCK_TooMany:
  342.     move.l (a2),d0 ; We have too many, but we tolerate that to some extent.
  343.     beq.b LKCK_ret
  344.     move.l d0,a0
  345.     move.l (a0),d0
  346.     beq.b LKCK_ret
  347.     move.l d0,a0
  348.     move.l (a0),d0
  349.     beq.b LKCK_ret
  350.  
  351.     moveq.l #0,d0 ; Now we are sure that we really have too many. Delete some.
  352.     move.l d0,(a1)
  353. LKCK_TooManyLoop:
  354.     move.l a2,a1
  355.     move.l (a1),a2
  356.     moveq.l #24,d0
  357.     jsr -210(a6) ; FreeMem
  358.     add.l #$10000,d6
  359.     move.l a2,d0
  360.     bne.b LKCK_TooManyLoop
  361. LKCK_ret:
  362.     move.l d7,(a3)
  363.     move.l (a7)+,d5
  364.     rts
  365.  
  366. exter_name: dc.b 'UAE filesystem',0
  367. doslibname: dc.b 'dos.library',0
  368. explibname: dc.b 'expansion.library',0
  369.     END
  370.